<template>
  <el-drawer
    v-model="renderVisible"
    :title="props.title"
    destroy-on-close
    :size="props.size"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <el-form
      ref="formRef"
      :label-position="'top'"
      :model="formData"
      :rules="formRules"
      style="height: 100%"
      scroll-to-error
      label-width="100px"
      v-loading="isLoading"
    >
      <el-tabs v-model="tabsData.active" class="global-drawer-tabs">
        <el-tab-pane label="基本信息" name="info">
          <el-divider content-position="left">商品信息</el-divider>
          <el-form-item label="商品标题" prop="title">
            <el-input
              v-model="formData.title"
              :maxlength="255"
              show-word-limit
            ></el-input>
          </el-form-item>
          <el-form-item label="商品副标题" prop="titleSub">
            <el-input
              v-model="formData.titleSub"
              :maxlength="255"
              show-word-limit
            ></el-input>
          </el-form-item>
          <el-form-item label="商品短标题" prop="titleShort">
            <el-input
              v-model="formData.titleShort"
              :maxlength="255"
              show-word-limit
            ></el-input>
          </el-form-item>
          <el-form-item label="关键词，逗号间隔" prop="keywords">
            <el-input
              v-model="formData.keywords"
              :maxlength="255"
              show-word-limit
            ></el-input>
          </el-form-item>

          <el-form-item label="商品图片" prop="albums">
            <UploadPanel
              v-model="formData.albums"
              :max="9"
              :compress-size="160"
            />
          </el-form-item>
          <el-form-item label="商品视频" prop="video">
            <UploadPanel v-model="formData.video" type="video" :max="1" />
          </el-form-item>

          <el-divider content-position="left">售价设置</el-divider>
          <el-form-item label="商品分类" prop="categoryId">
            <PipeSelectTree
              v-model="formData.categoryId"
              :options="categoryTree"
            />
          </el-form-item>
          <el-form-item label="商品类型" prop="type">
            <el-radio-group v-model="formData.type">
              <el-radio label="1">普通商品</el-radio>
              <el-radio label="2">积分商品</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="价格" prop="price">
            <el-input v-model="formData.price" v-decimal></el-input>
          </el-form-item>
          <el-form-item label="价格-原价" prop="priceOrigin">
            <el-input v-model="formData.priceOrigin" v-decimal></el-input>
          </el-form-item>
          <el-form-item label="奖励比例-直属上级" prop="firstAwardPercent">
            <el-input
              v-model="formData.firstAwardPercent"
              v-decimal="4"
            ></el-input>
          </el-form-item>
          <el-form-item label="奖励比例-上上级" prop="secondAwardPercent">
            <el-input
              v-model="formData.secondAwardPercent"
              v-decimal="4"
            ></el-input>
          </el-form-item>
          <el-form-item
            label="现金奖励-直属上级"
            prop="firstAwardCash"
            v-if="formData.type === '1'"
          >
            <el-input v-model="formData.firstAwardCash" v-decimal></el-input>
          </el-form-item>
          <el-form-item label="会员现金返佣" prop="userAwardCash">
            <el-input v-model="formData.userAwardCash" v-decimal></el-input>
          </el-form-item>

          <el-divider content-position="left">其他属性</el-divider>
          <el-form-item label="排序(数字越大越靠前)" prop="sort">
            <el-input-number
              v-model="formData.sort"
              :min="0"
              :max="9999999999"
              :controls="false"
            />
          </el-form-item>
          <el-form-item label="上架/下架" prop="state">
            <el-switch
              v-model="formData.state"
              :active-value="1"
              :inactive-value="0"
              active-color="#13ce66"
              inactive-color="#ff4949"
            />
          </el-form-item>
        </el-tab-pane>
        <el-tab-pane label="商品详情" name="content">
          <WangEditor v-model:content="formData.content" />
        </el-tab-pane>
        <el-tab-pane label="营销属性" name="attrs">
          <el-form-item label="营销属性">
            <el-checkbox
              v-model="formData.isRef"
              :true-label="1"
              :false-label="0"
              >推荐</el-checkbox
            >
            <el-checkbox
              v-model="formData.isNew"
              :true-label="1"
              :false-label="0"
              >新品</el-checkbox
            >
            <el-checkbox
              v-model="formData.isHot"
              :true-label="1"
              :false-label="0"
              >热卖</el-checkbox
            >
            <el-checkbox
              v-model="formData.isPostage"
              :true-label="1"
              :false-label="0"
              >包邮</el-checkbox
            >
            <el-checkbox
              v-model="formData.isReturn"
              :true-label="1"
              :false-label="0"
              >支持退货</el-checkbox
            >
          </el-form-item>
        </el-tab-pane>
        <el-tab-pane label="限购/销量" name="stock">
          <el-form-item label="限购" prop="restrict">
            <el-input-number
              v-model="formData.restrict"
              :min="0"
              :max="9999999999"
              :controls="false"
            />
          </el-form-item>
          <el-form-item label="日销" prop="saleCount">
            <el-input-number
              v-model="formData.saleCount"
              :min="0"
              :max="9999999999"
              :controls="false"
            />
          </el-form-item>
          <el-form-item label="月销" prop="saleMonth">
            <el-input-number
              v-model="formData.saleMonth"
              :min="0"
              :max="9999999999"
              :controls="false"
            />
          </el-form-item>
        </el-tab-pane>
        <el-tab-pane label="库存/规格" name="sku">
          <el-form-item label="商品类型" prop="type">
            <el-radio-group v-model="formData.type">
              <el-radio label="1">普通商品</el-radio>
              <el-radio label="2">积分商品</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="总库存" prop="stock">
            <el-input-number
              v-model="formData.stock"
              :min="0"
              :max="9999999999"
              :controls="false"
              :disabled="!!formData.isSpecs"
            />
            <el-checkbox
              v-model="formData.isSpecs"
              :false-label="0"
              :true-label="1"
              style="margin-left: 16px"
              @change="handleChangeModifySpecs"
              >启用商品多规格</el-checkbox
            >
          </el-form-item>
          <el-alert
            title="启用商品规格后，商品的价格及库存以商品规格为准，所有规格的库存必须等于总库存"
            type="info"
            :closable="false"
            style="margin-bottom: 20px"
          />
          <template v-if="!!formData.isSpecs">
            <el-form-item
              v-for="(item, index) in specsData"
              :label="item.title"
              :key="index"
            >
              <div class="tag-box">
                <el-tag
                  v-for="(_item, _index) in item.list"
                  :key="_item"
                  size="default"
                  type="info"
                  effect="plain"
                  >{{ _item }}</el-tag
                >
                <el-button
                  class="tag-btn"
                  :icon="Edit"
                  @click="handleClickEditSkuSpecsData(index)"
                  >关联规格属性</el-button
                >
              </div>
            </el-form-item>
            <div>
              <el-button
                type="primary"
                :icon="Edit"
                @click="handleClickEditSkuData"
              >
                关联多规格
              </el-button>
              <el-button
                type="primary"
                :icon="Refresh"
                @click="handleClickRefreshSku"
              >
                更新规格项目表格
              </el-button>
            </div>
            <el-alert
              v-if="isModifySpecs"
              title="规格发生变化，点击“更新规格项目表格”按钮，可重新生成表格"
              type="warning"
              :closable="false"
              style="margin-top: 20px"
            />
            <el-table
              :data="skuTableData"
              style="width: 100%; margin: 20px 0"
              border
            >
              <el-table-column
                v-for="item in skuTableFields"
                :key="item"
                :prop="item"
                :label="item"
              ></el-table-column>
              <el-table-column
                :label="formData.type === '1' ? '价格(元)' : '价格(积分)'"
              >
                <template #default="scope">
                  <el-input
                    v-model="scope.row.price"
                    v-decimal
                    @change="handleChangeRowMarkers"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column label="奖励比例-直属上级">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.firstAwardPercent"
                    v-decimal="4"
                    @change="handleChangeRowMarkers"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column label="奖励比例-上上级">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.secondAwardPercent"
                    v-decimal="4"
                    @change="handleChangeRowMarkers"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column
                label="现金奖励-直属上级"
                v-if="formData.type === '1'"
              >
                <template #default="scope">
                  <el-input
                    v-model="scope.row.firstAwardCash"
                    v-decimal
                    @change="handleChangeRowMarkers"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column label="会员现金返佣">
                <template #default="scope">
                  <el-input
                    v-model="scope.row.userAwardCash"
                    v-decimal
                    @change="handleChangeRowMarkers"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column label="库存">
                <template #default="scope">
                  <el-input-number
                    v-model="scope.row.stock"
                    :min="0"
                    :max="9999999999"
                    :controls="false"
                    @change="handleChangeRowSkuStock"
                  />
                </template>
              </el-table-column>
              <el-table-column label="限购">
                <template #default="scope">
                  <el-input-number
                    v-model="scope.row.restrict"
                    :min="0"
                    :max="9999999999"
                    :controls="false"
                    @change="handleChangeRowMarkers"
                  />
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-tab-pane>
        <el-tab-pane label="其它信息" name="other" v-if="formData.ownId">
          <el-descriptions
            class="global-descriptions"
            title="其它信息"
            border
            :column="1"
          >
            <el-descriptions-item label="OwnID">
              {{ formData.ownId }}
            </el-descriptions-item>
          </el-descriptions>
        </el-tab-pane>
      </el-tabs>
    </el-form>

    <template #footer>
      <PipeResetBtn
        :formEl="formRef"
        @clear="handleClickReset"
        :loading="isLoading"
        >重置</PipeResetBtn
      >
      <el-button
        type="primary"
        @click="handleClickSubmit(formRef)"
        :loading="isLoading"
        >提交</el-button
      >
    </template>
  </el-drawer>

  <DialogSku
    v-model="dialogSku.visible"
    :size="dialogSku.size"
    :title="dialogSku.title"
    :row-data="dialogSku.data"
    @on-complete="dialogSku.complete"
  />
</template>

<script setup lang="ts">
import { Edit, Refresh } from '@element-plus/icons-vue';
import { ref, reactive, watch, computed, PropType, inject } from 'vue';
import type { ElForm } from 'element-plus';
import { ElMessage, ElMessageBox } from 'element-plus';
import UploadPanel from '@/components/UploadPanel.vue';
import { createGoods, getGoodsDetail, updateGoods } from '@/apis/goods';
import * as _ from 'lodash';
import WangEditor from '@/components/WangEditor.vue';
import DialogSku from './dialog-sku.vue';
import { InitDrawerOpts, transformPromise } from '@/utils/common';
import { calcAdd } from '@/utils/util';

// 加载状态
const isLoading = ref(false);

// 弹窗
const dialogSku = reactive(
  InitDrawerOpts<{ specs: string; list: string[] }>({ size: '680px' })
);

// tabs
const tabsData = reactive({
  active: 'info'
});

// 商品分类
const categoryTree = inject('categoryTree');

// 表单 - ref
const formRef = ref<InstanceType<typeof ElForm>>();

// 表单数据
const CONST_STOCK = 10000;
const CONST_RESTRICT = 9999;
const GetFormData = (): API.goods.EntityDto => ({
  title: '',
  titleSub: '',
  titleShort: '',
  keywords: '',
  albums: '',
  cover: '',
  video: '',
  content: '',
  categoryId: 0,
  type: '1',
  price: '',
  priceOrigin: '',
  firstAwardPercent: '',
  secondAwardPercent: '',
  firstAwardCash: '',
  userAwardCash: '',
  stock: CONST_STOCK,
  restrict: CONST_RESTRICT,
  saleCount: 0,
  saleMonth: 0,
  sort: 9999,
  state: 1,
  isDel: 0,
  isRef: 1,
  isNew: 1,
  isHot: 1,
  isPostage: 1,
  isReturn: 0,
  // 是否启用商品规格
  isSpecs: 0,
  specs: '',
  // 标记sku有无变更
  isModifySku: false,
  skuList: []
});
const formData = ref(GetFormData());

// 标记规格有无变更
const isModifySpecs = ref(false);

interface GoodsSpecsData {
  title: string;
  list: string[];
}

// 获取当前商品的规格
const specsData = computed<GoodsSpecsData[]>({
  get: () => {
    if (!formData.value.specs) return [];
    return JSON.parse(formData.value.specs);
  },
  set: (val) => {
    formData.value.specs = JSON.stringify(val);
  }
});

// sku表格
interface SkuTableData extends API.goodsSku.EntitySchema {
  [name: string]: any;
}

// sku表格
const skuTableData = ref<SkuTableData[]>([]);

// sku表格的规格列
const skuTableFields = ref<string[]>([]);

// 表单 - 验证
const formRules = reactive({
  title: [{ required: true, trigger: 'blur', message: '请输入商品标题' }],
  titleSub: [{ required: true, trigger: 'blur', message: '请输入商品副标题' }],
  price: [{ required: true, trigger: 'blur', message: '请输入商品价格' }],
  categoryId: [{ required: true, trigger: 'change', message: '请选择商品分类' }]
});

// props
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },

  title: String,

  size: {
    type: [String, Number],
    default: '30%'
  },

  isEdit: {
    type: Boolean,
    default: false
  },

  rowData: {
    // type: Object as PropType<TempsPost>,
    type: Object as PropType<API.goods.EntitySchema>,
    default: () => ({})
  }
});

// emits
const emits = defineEmits(['update:modelValue', 'onRefresh']);

// computed - 抽屉[显示|隐藏]
const renderVisible = computed({
  get: () => props.modelValue,
  set: (val) => {
    emits('update:modelValue', val);
  }
});

// 获取详情
const requestDataDetail = () => {
  isLoading.value = true;
  getGoodsDetail(props.rowData.ownId!)
    .then((res) => {
      isLoading.value = false;
      formData.value = res.data;
      // 初始化分类
      formData.value.categoryId = res.data.category?.id ?? 0;
      // 初始化sku
      initSkuTableByDetail();
    })
    .catch(() => {
      isLoading.value = false;
    });
};

/**
 * 初始化sku表格
 *
 * @todo 根据 specsData 进行组合生成数据
 * @todo 将[红色,蓝色][大,小]等数组，转为["红色,大", "红色,小", "蓝色,小", "蓝色,小"]
 */
const initSkuTable = () => {
  if (!specsData.value || !specsData.value.length) {
    skuTableFields.value = [];
    skuTableData.value = [];
    return;
  }

  // 逗号间隔的字符串
  const skuFields: string[] = [];
  let tempStrList: string[] = [];
  specsData.value.forEach((specsItem) => {
    skuFields.push(specsItem.title);
    let tempList: string[][] = [];

    let i = 0;
    do {
      const str = tempStrList[i] || '';
      tempList.push(
        specsItem.list.map((item) => (str ? `${str},${item}` : item))
      );
      i++;
    } while (i < tempStrList.length);

    tempStrList = tempList.flat();
  });

  // 创建数据
  const result = tempStrList.map((specsStr) => {
    // 将specs分割多个字段
    const specsFields: { [name: string]: string } = {};

    specsStr.split(',').forEach((strVal, strIndex) => {
      specsFields[skuFields[strIndex]] = strVal;
    });

    return {
      ...specsFields,
      specs: specsStr,
      price: formData.value.price || '0',
      stock: CONST_STOCK,
      restrict: formData.value.restrict || CONST_RESTRICT,
      firstAwardPercent: formData.value.firstAwardPercent || '',
      secondAwardPercent: formData.value.secondAwardPercent || '',
      firstAwardCash: formData.value.firstAwardCash || '',
      userAwardCash: formData.value.userAwardCash || ''
    };
  });

  skuTableFields.value = skuFields;
  skuTableData.value = result;
};

/**
 * 回显sku表格
 *
 * @todo 初始化sku表格
 * @tood 将detail的sku回显
 */
const initSkuTableByDetail = () => {
  initSkuTable();

  // 转换数据
  const tempObj = (formData.value.skuList || []).reduce(
    (
      accumulator: { [name: string]: API.goodsSku.EntitySchema },
      currentValue
    ) => {
      accumulator[currentValue.specs] = currentValue;
      return accumulator;
    },
    {}
  );

  // 覆盖数据
  skuTableData.value.forEach((item) => {
    Object.assign(item, tempObj[item.specs]);
  });

  // 更新总库存
};

// 初始化数据
const initPageData = () => {
  // 还原数据
  isModifySpecs.value = false;
  skuTableFields.value = [];
  skuTableData.value = [];

  // 当rowData发生变化，初始化数据
  if (props.isEdit) {
    // 从接口拿数据
    requestDataDetail();
  } else {
    formData.value = GetFormData();
  }
};

// watch
watch(
  () => props.modelValue,
  (val) => {
    if (!val) return;

    initPageData();
  },
  {
    immediate: true
  }
);

// btn - 关联多规格
const handleClickEditSkuData = async () => {
  dialogSku.title = '关联多规格';
  dialogSku.data = {
    specs: '',
    list: specsData.value.map((item) => item.title)
  };
  dialogSku.visible = true;
  const res = await transformPromise<string[]>(dialogSku);
  if (res.action !== 'submit') return;

  // 增量修改源数据
  const result: GoodsSpecsData[] = res.result.map((specsName) => {
    return (
      specsData.value.find((item) => item.title === specsName) || {
        title: specsName,
        list: []
      }
    );
  });
  specsData.value = result;

  // 标记发生变更
  isModifySpecs.value = true;
};

// btn - 关联规格属性
const handleClickEditSkuSpecsData = async (index: number) => {
  const rowData: GoodsSpecsData = specsData.value[index];

  dialogSku.title = '关联规格属性';
  dialogSku.data = {
    specs: rowData.title,
    list: rowData.list
  };
  dialogSku.visible = true;
  const res = await transformPromise<string[]>(dialogSku);
  if (res.action !== 'submit') return;

  // 全量修改源数据
  const result: GoodsSpecsData[] = JSON.parse(JSON.stringify(specsData.value));
  result[index].list = res.result;
  specsData.value = result;

  // 标记发生变更
  isModifySpecs.value = true;
};

/**
 * btn - 更新规格项目表格
 *
 * @todo 初始化sku表格
 * @todo 更新总库存
 * @todo 打标记
 */
const handleClickRefreshSku = () => {
  initSkuTable();

  // 更新总库存
  updateTotalStock();

  // 关闭提示
  isModifySpecs.value = false;

  // 标记sku有变更
  formData.value.isModifySku = true;
};

/**
 * 更新总库存
 *
 * @todo 统计sku所有库存
 */
const updateTotalStock = () => {
  formData.value.stock = skuTableData.value.reduce(
    (accumulator, currentValue) =>
      +calcAdd(accumulator, currentValue.stock || 0),
    0
  );
};

/**
 * checkbox change - 是否开启多规格 - 回调
 *
 * @todo 开启后，更新总库存
 */
const handleChangeModifySpecs = (val: number) => {
  if (val) updateTotalStock();
};

/**
 * input change - 修改sku的库存 - 回调
 *
 * @todo 修改后，更新总库存
 * @todo 打标记
 */
const handleChangeRowSkuStock = () => {
  updateTotalStock();
  formData.value.isModifySku = true;
};

/**
 * input change - 修改后打标记 - 回调
 *
 * @todo 修改价格
 * @todo 修改限购
 * @todo 修改奖励比例-直属上级
 * @todo 修改奖励比例-上上级
 * @todo 修改现金奖励-直属上级
 */
const handleChangeRowMarkers = () => {
  formData.value.isModifySku = true;
};

// btn - reset
const handleClickReset = () => {
  initPageData();
};

// btn - submit
const handleClickSubmit = async (
  formEl: InstanceType<typeof ElForm> | undefined
) => {
  // 二次确认
  if (isModifySpecs.value) {
    return await ElMessageBox.alert(
      '商品规格发生变化，且未“更新规格项目表格”，请核对数据！',
      '库存/规格',
      {
        confirmButtonText: '取消修改'
      }
    );
  }

  // 二次确认
  if (!formData.value.stock) {
    try {
      await ElMessageBox.confirm(
        '请核实商品信息，库存为零，则直接进入仓库',
        '商品信息',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      );
    } catch (error) {
      return;
    }
  }

  if (!formEl) return;
  formEl.validate(async (valid, error) => {
    if (!valid) {
      // 提示第一个错误
      const keylist = Object.keys(error!);
      const message = error![keylist[0]]?.[0]?.message || '';
      ElMessage.error(message);

      return;
    }

    // 将图集第一张作为封面图
    formData.value.cover = formData.value.albums?.split(',')?.[0] || '';
    // sku
    formData.value.skuList = skuTableData.value.length
      ? skuTableData.value.map((item) => ({
          ...item,
          firstAwardPercent: item.firstAwardPercent || null,
          secondAwardPercent: item.secondAwardPercent || null,
          firstAwardCash: item.firstAwardCash || null,
          userAwardCash: item.userAwardCash || null
        }))
      : undefined;

    // 将空字符串转undefined
    if (formData.value.priceOrigin === '') formData.value.priceOrigin = null;
    if (formData.value.firstAwardPercent === '')
      formData.value.firstAwardPercent = null;
    if (formData.value.secondAwardPercent === '')
      formData.value.secondAwardPercent = null;
    if (formData.value.firstAwardCash === '')
      formData.value.firstAwardCash = null;
    if (formData.value.userAwardCash === '')
      formData.value.userAwardCash = null;
    if (formData.value.specs === '') formData.value.specs = null;

    if (props.isEdit) {
      submitDataUpdate(formData.value);
    } else {
      submitDataAdd(formData.value);
    }
  });
};

// submit - add
const submitDataAdd = (dataOpt: API.goods.EntityDto) => {
  isLoading.value = true;
  createGoods(dataOpt)
    .then((res) => {
      isLoading.value = false;
      ElMessage.success(res.message);
      // 关闭弹窗
      emits('onRefresh');
      renderVisible.value = false;
    })
    .catch(() => {
      isLoading.value = false;
    });
};

// submit - update
const submitDataUpdate = (dataOpt: API.goods.EntityDto) => {
  isLoading.value = true;
  updateGoods(props.rowData.ownId!, dataOpt)
    .then((res) => {
      isLoading.value = false;
      ElMessage.success(res.message);
      // 关闭弹窗
      emits('onRefresh');
      renderVisible.value = false;
    })
    .catch(() => {
      isLoading.value = false;
    });
};
</script>

<style lang="scss" scoped>
:deep(.el-input-number) .el-input__inner {
  text-align: left;
}
.tag-box {
  .el-tag {
    margin: 0 8px 8px 0;
  }
  .tag-btn {
    margin: 0 8px 8px 0;
  }
}
</style>
